/*
 * Copyright (C) 2009 Leandro Aparecido <lehphyro@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.metalframework.jsf.navigation;

import org.metalframework.util.*;

public class NavigationRule {

	private String viewId;
	private String when;
	private boolean whenNull;
	private boolean whenNotNull;
	private Class<? extends Throwable> onThrowable;
	private boolean redirect;
	private boolean fallback;

	public boolean isActivated(Object returnValue, Throwable throwable) {
		boolean activated = false;
		
		if (throwable == null) {
			activated = isActivatedByWhens(returnValue);
		} else {
			if (!IgnoreThrowableException.class.isAssignableFrom(onThrowable) &&
				onThrowable.isAssignableFrom(throwable.getClass())) {
				activated = true;
			} else {
				activated = isActivatedByWhens(returnValue);
			}
		}
		
		return activated;
	}
	
	public boolean isDefaultCondition() {
		return IgnoreThrowableException.class.isAssignableFrom(onThrowable) &&
			when == null &&
			!whenNull &&
			!whenNotNull;
	}
	
	protected boolean isActivatedByWhens(final Object returnValue) {
		boolean activated = false;
		
		if (when == null) {
			if (whenNull && returnValue == null) {
				activated = true;
			} else if (whenNotNull && returnValue != null) {
				activated = true;
			}
		} else {
			Boolean resolvedWhen = FacesUtils.resolve(when, Boolean.class);
			if (Boolean.TRUE.equals(resolvedWhen)) {
				activated = true;
			}
		}
		
		return activated;
	}
	
// Getters/Setters

	public String getViewId() {
		return viewId;
	}

	public void setViewId(String viewId) {
		this.viewId = viewId;
	}

	public String getWhen() {
		return when;
	}

	public void setWhen(String when) {
		this.when = when;
	}

	public boolean isWhenNull() {
		return whenNull;
	}

	public void setWhenNull(boolean whenNull) {
		this.whenNull = whenNull;
	}

	public boolean isWhenNotNull() {
		return whenNotNull;
	}

	public void setWhenNotNull(boolean whenNotNull) {
		this.whenNotNull = whenNotNull;
	}

	public Class<? extends Throwable> getOnThrowable() {
		return onThrowable;
	}

	public void setOnThrowable(Class<? extends Throwable> onThrowable) {
		this.onThrowable = onThrowable;
	}
	
	public boolean isRedirect() {
		return redirect;
	}
	
	public void setRedirect(boolean redirect) {
		this.redirect = redirect;
	}

	public boolean isFallback() {
		return fallback;
	}
	
	public void setFallback(boolean fallback) {
		this.fallback = fallback;
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		
		sb.append("viewId=").append(viewId);
		sb.append(";when=").append(when);
		sb.append(";whenNull=").append(whenNull);
		sb.append(";whenNotNull=").append(whenNotNull);
		sb.append(";onThrowable=").append(onThrowable.getSimpleName());
		sb.append(";redirect=").append(redirect);
		sb.append(";fallback=").append(fallback);
		
		return sb.toString();
	}
}
